class myPromise {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    constructor(executor) {
        this.status = myPromise.PENDING
        this.value = null
        this.callback = []
        //使用try  是因为 外面使用不调用resolve  reject以外其他的 将会报错
        try {
            executor(this.resolve.bind(this), this.reject.bind(this))
        } catch (error) {
            this.reject(error)
        }
    }
    resolve(value) {
        if (this.status === myPromise.PENDING) {
            this.status = myPromise.FULFILLED
            this.value = value
            setTimeout(() => {// then的值需要在reject或resolve之后执行
                this.callback.map(item => {
                    item.onFulfilled(value)
                })
            })
        }
    }
    reject(reason) {
        if (this.status === myPromise.PENDING) {
            this.status = myPromise.REJECTED
            this.value = reason
            setTimeout(() => {
                this.callback.map(item => {
                    item.onRejected(reason)
                })
            })
        }
    }
    then(onFulfilled, onRejected) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value //then().then穿透
        } if (typeof onRejected !== 'function') {
            onRejected = () => this.value
        }
        return new myPromise((resolve, reject) => {
            //执行resole reject里面异步 只要等待后才能then
            if (this.status === myPromise.PENDING) {
                this.callback.push({
                    onFulfilled: value => {
                        try {
                            let result = onFulfilled(value)
                            console.log(result)

                            if (result instanceof myPromise) {
                                result.then(resolve, reject)
                            } else {
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    },
                    onRejected: value => {
                        try {
                            let result = onRejected(value)
                            if (result instanceof myPromise) {
                                result.then(resolve, reject)
                            } else {
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    }
                })
            }
            //在没有resolve和reject之前就不能执行then
            if (this.status === myPromise.FULFILLED) {
                setTimeout(() => {//异步比同步晚执行
                    try { //解决then回调后 错误
                        let result = onFulfilled(this.value)
                        //解决 then里面传递promise
                        if (result instanceof myPromise) {
                            result.then(resolve, reject)
                            // result.then(value => {
                            //     resolve(value)
                            // }, reason => {
                            //     reject(reason)
                            // })
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                })
            }

            if (this.status === myPromise.REJECTED) {
                setTimeout(() => {
                    try {
                        let result = onRejected(this.value)
                        if (result instanceof myPromise) {
                            result.then(resolve, reject)
                            // result.then(value => {
                            //     resolve(value)
                            // }, reason => {
                            //     reject(reason)
                            // })
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                })
            }
        })
    }
}